﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VMC.Domain.Repository;
using VMC.Domain.Service.Abstract;
using System.Linq.Expressions;
namespace VMC.Domain.Service
{
    public class Service<TObject> : IService<TObject> where TObject : class
    {
        protected Repository<TObject> repository;
        protected ValidationState VState;
        public Service()
        {
            repository = new Repository<TObject>();
            VState = new ValidationState();
        }
        
        public virtual IEnumerable<TObject> All(){
            return repository.All().AsEnumerable();
        }

        public bool Contains(Expression<Func<TObject, bool>> predicate)
        {
            return repository.Contains(predicate);
        }


        public IEnumerable<TObject> Search(Expression<Func<TObject, bool>> predicate)
        {

            return repository.Filter(predicate);
        }

        public IEnumerable<TObject> Search(Expression<Func<TObject, bool>> query, out int total, int index = 0, int size = 50)
        {
            return repository.Filter<TObject>(query, out total, index, size);
        }


        public void Dispose()
        {
            if (repository != null)
                repository.Dispose();
        }
        
        public virtual TObject Create(TObject EntityInstance, out bool status)
        {
            VState.ClearValidation();
            status = false;
            if (Validate(EntityInstance))
                {
                    TObject _entityInstance  = repository.Create(EntityInstance);
                    if(_entityInstance != null) status = true;
                    else VState.AddError("", "Unable to save provided information.");
                    return _entityInstance;
                }
            else 
                return null; 
        }

        public virtual TObject Update(TObject EntityInstance, out bool status)
        {
            VState.ClearValidation();
            status = false;
            if (Validate(EntityInstance))
            {
                if (repository.Update(EntityInstance) == 1)
                    status = true;
                else
                    VState.AddError("", "Unable to update information.");
            }
            return EntityInstance;
        }

        public virtual bool Delete(int ID) { return false; }

        public virtual bool Validate(TObject EntityInstance) { return true; }
        public virtual TObject Find(int ID) { return null; }

        public virtual Dictionary<string, string> GetValidationErrors()
        {
            return VState.ValidationErrors;
        }
    }
}
